from django.db import models
from django.contrib.auth.models import User


class Project(models.Model):
    """项目管理"""
    name = models.CharField(max_length=100, verbose_name='项目名称')
    description = models.TextField(verbose_name='项目描述', blank=True)
    creator = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='创建人')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '项目'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):
        return self.name


class Environment(models.Model):
    """环境管理"""
    name = models.CharField(max_length=50, verbose_name='环境名称')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目')
    base_url = models.URLField(verbose_name='基础URL')
    description = models.TextField(verbose_name='环境描述', blank=True)
    headers = models.JSONField(verbose_name='公共请求头', default=dict, blank=True)
    variables = models.JSONField(verbose_name='环境变量', default=dict, blank=True)

    class Meta:
        verbose_name = '环境配置'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.project.name}-{self.name}"


class ApiInterface(models.Model):
    """接口管理"""
    HTTP_METHODS = (
        ('GET', 'GET'),
        ('POST', 'POST'),
        ('PUT', 'PUT'),
        ('DELETE', 'DELETE'),
        ('PATCH', 'PATCH'),
    )

    name = models.CharField(max_length=100, verbose_name='接口名称')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目')
    path = models.CharField(max_length=200, verbose_name='接口路径')
    method = models.CharField(max_length=10, choices=HTTP_METHODS, verbose_name='请求方法')
    description = models.TextField(verbose_name='接口描述', blank=True)
    headers = models.JSONField(verbose_name='请求头', default=dict, blank=True)
    params = models.JSONField(verbose_name='请求参数', default=dict, blank=True)
    body = models.JSONField(verbose_name='请求体', default=dict, blank=True)
    creator = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='创建人')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '接口'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):
        return f"{self.project.name}-{self.name}"


class TestCase(models.Model):
    """测试用例管理"""
    STATUS_CHOICES = (
        ('active', '启用'),
        ('inactive', '禁用'),
    )

    name = models.CharField(max_length=100, verbose_name='用例名称')
    interface = models.ForeignKey(ApiInterface, on_delete=models.CASCADE, verbose_name='关联接口')
    description = models.TextField(verbose_name='用例描述', blank=True)
    priority = models.IntegerField(verbose_name='优先级', default=3)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='active', verbose_name='状态')
    pre_conditions = models.JSONField(verbose_name='前置条件', default=dict, blank=True, help_text='''
    {
        "handlers": [  # 前置处理器列表
            "database_setup",
            "variable_setup",
            "logging"
        ],
        "database_setup": {  # 数据库准备配置
            "table": "users",
            "data": [
                {"username": "test_user", "email": "test@example.com"}
            ]
        },
        "variables": {  # 变量配置
            "user_id": 1,
            "token": "xxx"
        }
    }
    ''')
    post_conditions = models.JSONField(verbose_name='后置条件', default=dict, blank=True, help_text='''
    {
        "handlers": [  # 后置处理器列表
            "data_cleanup",
            "notification"
        ],
        "data_cleanup": {  # 数据清理配置
            "tables": ["users", "orders"]
        },
        "notifications": {  # 通知配置
            "type": "email",
            "recipients": ["admin@example.com"]
        }
    }
    ''')
    test_data = models.JSONField(verbose_name='测试数据')
    expected_results = models.JSONField(verbose_name='预期结果')
    dependencies = models.JSONField(verbose_name='依赖配置', default=dict, blank=True, help_text='''
    {
        "cases": [  # 依赖的测试用例列表
            {
                "case_id": 1,  # 依赖的测试用例ID
                "required": true,  # 是否必须成功
                "variables": ["token", "user_id"]  # 需要使用的变量
            }
        ],
        "strategy": "all_success"  # 依赖策略：all_success（全部成功）, any_success（任一成功）
    }
    ''')
    creator = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='创建人')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '测试用例'
        verbose_name_plural = verbose_name
        ordering = ['priority', '-created_time']

    def __str__(self):
        return f"{self.interface.name}-{self.name}"


class TestExecution(models.Model):
    """测试执行记录"""
    STATUS_CHOICES = (
        ('pending', '待执行'),
        ('running', '执行中'),
        ('completed', '已完成'),
        ('error', '执行错误'),
    )

    RESULT_CHOICES = (
        ('pass', '通过'),
        ('fail', '失败'),
        ('error', '错误'),
        ('skip', '跳过'),
    )

    test_case = models.ForeignKey(TestCase, on_delete=models.CASCADE, verbose_name='测试用例')
    environment = models.ForeignKey(Environment, on_delete=models.CASCADE, verbose_name='执行环境')
    executor = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='执行人')
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending', verbose_name='执行状态')
    result = models.CharField(max_length=10, choices=RESULT_CHOICES, null=True, verbose_name='执行结果')
    start_time = models.DateTimeField(null=True, verbose_name='开始时间')
    end_time = models.DateTimeField(null=True, verbose_name='结束时间')
    request_data = models.JSONField(verbose_name='请求数据')
    response_data = models.JSONField(verbose_name='响应数据', null=True)
    error_message = models.TextField(verbose_name='错误信息', blank=True)

    class Meta:
        verbose_name = '测试执行'
        verbose_name_plural = verbose_name
        ordering = ['-start_time']
        default_manager_name = 'objects'  # 使用默认管理器
        managed = True  # 由 Django 管理数据库表
        swappable = False  # 不可替换
        abstract = False  # 不是抽象类

    def __str__(self):
        return f"{self.test_case.name}-{self.start_time}"


class TestReport(models.Model):
    """测试报告管理"""
    name = models.CharField(max_length=100, verbose_name='报告名称')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目')
    creator = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='创建人')
    created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    start_time = models.DateTimeField(verbose_name='测试开始时间')
    end_time = models.DateTimeField(verbose_name='测试结束时间')
    total_cases = models.IntegerField(verbose_name='用例总数')
    passed_cases = models.IntegerField(verbose_name='通过用例数')
    failed_cases = models.IntegerField(verbose_name='失败用例数')
    error_cases = models.IntegerField(verbose_name='错误用例数')
    skipped_cases = models.IntegerField(verbose_name='跳过用例数')
    summary = models.TextField(verbose_name='测试总结', blank=True)
    executions = models.ManyToManyField(TestExecution, verbose_name='执行记录')

    class Meta:
        verbose_name = '测试报告'
        verbose_name_plural = verbose_name
        ordering = ['-created_time']

    def __str__(self):
        return self.name
